package com.jjlin.chapter_2;

import java.util.*;
//将单链表的每k个节点之间逆序
public class CD119{
    public static class Node{
        public int val;
        public Node next;
        public Node(int data){
            this.val = data;
        }
    }

    //创建单链表
    public static Node createNodeList(int[] nums){
        Node head = new Node(nums[0]);
        Node pre = head;
        Node cur = null;
        for(int i = 1; i < nums.length; i++){
            cur = new Node(nums[i]);
            pre.next = cur;
            pre = cur;
        }
        return head;
    }

    //打印单链表
    public static void printNodeList(Node head){
        Node cur = head;
        while(cur != null){
            System.out.print(cur.val + " ");
            cur = cur.next;
        }
    }

    //解法1：利用stack将单链表的每k个节点之间逆序，时间复杂度为O(N),空间复杂度为O(N)
    public static Node reverseNodeList(Node head, int k){
        if(head == null || k < 2)
            return head;
        Stack<Node> stack = new Stack<>();
        Node cur = head;
        Node next = null;
        Node pre = null;
        Node newhead = head;
        while(cur != null){
            next = cur.next;
            stack.push(cur);
            if(stack.size() == k){
                pre = reverse(stack, pre, next);
                newhead = newhead == head ? cur : newhead;
            }
            cur = next;
        }
        return newhead;
    }

    //将stack中的节点逆序，pre为上k个节点的最后一个节点，next为下一个节点的第一个节点
    public static Node reverse(Stack<Node> stack, Node pre, Node next){
        Node cur = stack.pop();
        if(pre != null){
            pre.next = cur;
        }
        while(!stack.isEmpty()){
            cur.next = stack.pop();
            cur = cur.next;
        }
        cur.next = next;
        return cur;
    }

    //解法2：直接将单链表的每k个节点之间逆序，时间复杂度为O(N),空间复杂度为O(1)
    public static Node reverseNodeList1(Node head, int k){
        if(head == null || k < 2)
            return head;
        int count = 0;
        Node cur = head;
        Node next = null;
        Node pre = null;
        Node start = null;
        while(cur != null){
            count++;
            next = cur.next;
            if(count == k){
                start = pre == null ? head : pre.next;
                head = pre == null ? cur : head;
                pre = reverse1(pre, start, cur, next);
                count = 0;
            }
            cur = next;
        }
        return head;
    }

    //逆序从start到end节点的链表，其中left为start的上一个节点，right为end的下一个节点
    public static Node reverse1(Node left, Node start, Node end, Node right){
        Node pre = start;
        Node cur = start.next;
        Node next = null;
        while(cur != right){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        if(left != null)
            left.next = end;
        start.next = right;
        return start;
    }

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] nums = new int[n];
        for(int i = 0; i < n; i++){
            nums[i] = sc.nextInt();
        }
        int k = sc.nextInt();
        Node head = createNodeList(nums);
        head = reverseNodeList1(head, k);
        printNodeList(head);
    }
}
